package com.ruoyi.warehousemanager.controller;

import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.warehousemanager.domain.Check;
import com.ruoyi.warehousemanager.domain.Item;
import com.ruoyi.warehousemanager.domain.NewApply;
import com.ruoyi.warehousemanager.domain.Operate;
import com.ruoyi.warehousemanager.pojo.CheckVo;
import com.ruoyi.warehousemanager.pojo.ItemVO;
import com.ruoyi.warehousemanager.service.INewApplyService;
import com.ruoyi.warehousemanager.service.IOperateService;
import com.ruoyi.warehousemanager.service.ItemService;
import lombok.experimental.Accessors;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.warehousemanager.service.ICheckService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 审核管理Controller
 *
 * @author zyx
 * @date 2023-05-15
 */
@RestController
@RequestMapping("/warehousemanager/check")
@Accessors(chain = true)
public class CheckController extends BaseController {

    @Autowired
    private ICheckService checkService;

    @Autowired
    private ItemService itemService;

    @Autowired
    private IOperateService operateService;

    @Autowired
    private INewApplyService newApplyService;

    @Autowired
    private ISysUserService userService;


    /**
     * 查询审核管理列表
     */
    @PreAuthorize("@ss.hasPermi('warehousemanager:check:list')")
    @GetMapping("/list")
    public TableDataInfo list(CheckVo check) {

        startPage();
        List<CheckVo> list = checkService.selectCheckList(check);

        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getItemId() == null) {
                list.get(i).setItemName(list.get(i).getCheckRemark());
            }
        }
        return getDataTable(list);
    }

    /**
     * 导出审核管理列表
     */
    @PreAuthorize("@ss.hasPermi('warehousemanager:check:export')")
    @Log(title = "审核管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, CheckVo check) {
        List<CheckVo> list = checkService.selectCheckList(check);
        ExcelUtil<CheckVo> util = new ExcelUtil<CheckVo>(CheckVo.class);
        util.exportExcel(response, list, "审核管理数据");
    }

    /**
     * 获取审核管理详细信息
     */
    @PreAuthorize("@ss.hasPermi('warehousemanager:check:query')")
    @GetMapping(value = "/{checkId}")
    public AjaxResult getInfo(@PathVariable("checkId") Long checkId) {
        return success(checkService.selectCheckByCheckId(checkId));
    }

    /**
     * 新增审核管理·
     */
    @PreAuthorize("@ss.hasPermi('warehousemanager:check:add')")
    @Log(title = "审核管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Check check) {
        return toAjax(checkService.insertCheck(check));
    }

    /**
     * 修改（通过/驳回申请---审核表更新）
     */
    @PreAuthorize("@ss.hasPermi('warehousemanager:check:update')")
    @Log(title = "审核管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody CheckVo check) {
        return applyItemsOperate(check);
    }

    //多选修改：通过/驳回申请
    @PreAuthorize("@ss.hasPermi('warehousemanager:check:update')")
    @Log(title = "审核管理", businessType = BusinessType.UPDATE)
    @PostMapping("/multiple")
    public AjaxResult mutipleEdit(@RequestBody List<CheckVo> checks) {
        StringBuilder msg = new StringBuilder();
        Integer count = 0;
        for (CheckVo c : checks) {
            try {
                AjaxResult ajaxResult;
                ajaxResult = applyItemsOperate(c); //{msg=1, code=200, data=申请物品为新物品或在仓库中已无库存}

                if (!(ajaxResult.get("msg") == "0")) {
                    count++;
                    msg.append(c.getItemName() + "、");
                }
            } catch (Exception e) {
                count++;
                msg.append(c.getItemName() + " ");
            }
        }
        if (count!=0){
            msg.insert(0, "操作成功，其中失败" + count + "次，申请失败的物品分别为：").replace(msg.length() - 1, msg.length(), "。");
        }else {
            msg.insert(0, "操作成功，其中失败" + count + "次");
        }
        return AjaxResult.success(msg.toString(), msg);
    }

    /**
     * 删除审核管理
     */
    @PreAuthorize("@ss.hasPermi('warehousemanager:check:remove')")
    @Log(title = "审核管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{checkIds}")
    public AjaxResult remove(@PathVariable Long[] checkIds) {
        return toAjax(checkService.deleteCheckByCheckIds(checkIds));
    }

    /*审核操作过程如下：
        1.审核通过
            1.1物品申请
                1.1.1物品库存为0或不存在 采购表中登记此物品信息；审核表更新对应数据
                1.1.2有库存
                    1）库存足够 更新物品表中车间和工区对应物品的数量；审核表更新对应数据
                        工区有物品：工区和车间物品数量更新
                        工区无物品：工区插入数据，车间减少数量
                    2）库存不够 驳回申请，更新审核表数据
            1.2外库申请
                外库表中添加数据；审核表更新；物品表更新
        2.审核驳回
            操作审核表更新对应数据
    */
    public AjaxResult applyItemsOperate(CheckVo check) {
        if (check.getStatus().equals("0")) {
            //审核通过
            //车间仓库itemFromWorkshop
            Item itemFromWorkshop = new Item();
            itemFromWorkshop.setDeptId(check.getDeptId());
            itemFromWorkshop.setItemName(check.getItemName());

            List<ItemVO> itemsForWorkshop = itemService.selectItemList(itemFromWorkshop);

            if (check.getApplyType().equals("1")) {
                //物品申请
                //车间库存为0或物品不存在
                if (itemsForWorkshop.size() == 0 ? true : (itemsForWorkshop.get(0).getItemNum() == 0 ? true : false)) {
                    //驳回请求
                    check.setStatus("1");
                    check.setContent("申请物品为新物品或在仓库中已无库存");
                    NewApply newApply = NewApply.builder()
                            .itemName(check.getItemName())
                            .itemNum(check.getItemNum())
                            .itemUnit(check.getItemUnit())
                            .applicant(check.getCheckApplicant())
                            .applicationTime(check.getCheckApplicationTime())
                            .build();

                    newApplyService.insertNewApply(newApply);
                    //给出提示
                    try {
                        checkService.updateCheck(check);
                    } catch (Exception e) {
                        return AjaxResult.error();
                    }
                    return AjaxResult.success("1", check.getContent());
                } else {
                    //车间存在库存---------------------
                    long numMinus = itemsForWorkshop.get(0).getItemNum() - check.getItemNum();
                    if (Math.toIntExact(numMinus) >= 0) {
                        //库存足够
                        if (check.getItemId() != null) {
                            //工区存在此物品
                            Item item = itemService.selectItemByItemId(check.getItemId());
                            item.setItemNum(check.getItemNum() + item.getItemNum());
                            itemService.updateItem(item);//工区更新仓库数量
                        } else {
                            //工区没有此itemId,不存在此物品，确定为新增物品
                            //获取添加时间
                            Date date = new Date();

                            //获取申请用户的deptId
                            SysUser sysUser = userService.selectUserByUserName(check.getCheckApplicant());

                            Item item = Item.builder()
                                    .itemName(check.getCheckRemark())
                                    .itemNum(check.getItemNum())
                                    .itemUnit(itemsForWorkshop.get(0).getItemUnit())
                                    .deptId(sysUser.getDeptId())
                                    .typeId(itemsForWorkshop.get(0).getTypeId())
                                    .updateTime(date).build();

                            itemService.insertItem(item);
                        }
                        itemsForWorkshop.get(0).setItemNum(numMinus);
                        itemService.updateItem(itemsForWorkshop.get(0));//车间更新仓库数量

                        try {
                            checkService.updateCheck(check);//审核表更新
                        } catch (Exception e) {
                            return AjaxResult.error();
                        }
                        return AjaxResult.success("0", "操作成功");
                    } else {
                        //库存不足
                        check.setStatus("1");
                        check.setContent("数量不足,仓库中物品数量为" + itemsForWorkshop.get(0).getItemNum());
                        try {
                            checkService.updateCheck(check);
                        } catch (Exception e) {
                            return AjaxResult.error();
                        }
                        return AjaxResult.success("2", check.getContent());
                    }
                }
            } else {
                //外库申请
                Item item = itemService.selectItemByItemId(check.getItemId());

                long numMinus = item.getItemNum() - check.getItemNum();
                item.setItemNum(numMinus);
                itemService.updateItem(item);//车间更新仓库数量

                Operate operate = Operate.builder()
                        .itemId(check.getItemId())
                        .itemNum(check.getItemNum())
                        .deptId(item.getDeptId())
                        .operateType(check.getApplyOperateType())
                        .operateRemark(check.getCheckRemark())
                        .operateTime(new Date())
                        .build();

                operateService.insertOperate(operate);
                try {
                    checkService.updateCheck(check);
                } catch (Exception e) {
                    return AjaxResult.error();
                }
                return AjaxResult.success("0", "操作成功");
            }
        } else {
            //审核驳回
            try {
                checkService.updateCheck(check);
            } catch (Exception e) {
                return AjaxResult.error();
            }
            return AjaxResult.success("0", "操作成功");
        }
    }
}
